#ifndef Shared_Memory_Model_Set_h
#define Shared_Memory_Model_Set_h

#include <math.h>
#include "util.h"
#include <stdio.h>
using namespace std;

static bool PrintBin;
using namespace std;

#define nSets        16384
#define nBytesInLine 64
#define nTagBits     12
#define nIndexBits   14
#define nOffSetBits  6

#define OffSetMask  0x3f
#define IndexMask   0x3fff
#define TagMask     0xfff

class Set {
    
public:    
    unsigned int offset : 6;
    unsigned int index : 14;
    unsigned int tag : 12;
    bool valid;
    
    unsigned int address;
    unsigned int data[nBytesInLine/4];
    
// methods     
    
    void setAddress(unsigned int addr)
    {
        address = addr;
        offset  = addr & OffSetMask;  addr = (addr >> nOffSetBits);
        index   = addr & IndexMask; addr = (addr >> nIndexBits);  
        tag     = addr & TagMask;
        valid   = true;
    }
    
    void clear(){
        valid = false;
    }
    
    Set(){valid = false; PrintBin = false;}    

    Set(unsigned int addr)
    {
        this->setAddress(addr);
    }
    
    friend ostream& operator<<(ostream& lhs, const Set& rhs)
    {
        char buf_a[1024] = {"Hello world\n"};
        char temp[33];
        if (!PrintBin)
            sprintf(buf_a, "Tag/Index/Offset: %x / %x / %x Address = %x ",rhs.tag,rhs.index,rhs.offset, rhs.address);
        else
            sprintf(buf_a, "Tag/Index/Offset: %s / %s / %s Address = %s ",hexToBinary(rhs.tag, temp) ,hexToBinary(rhs.index, temp),hexToBinary(rhs.offset, temp), hexToBinary(rhs.address, temp));
        
        lhs << buf_a;
        
        if (rhs.valid) {
           lhs << "Valid ";
        }

        return lhs;
    }

};

#endif
